/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "queue.h"
#include "semphr.h"
#include "stm32f1xx_hal_flash.h"
#include "modbus_rtu.h"
#include "ina226.h"
#define GpuSend(...) printf(__VA_ARGS__)  
//#define GpuSend(...) SOFTUART_Printf(__VA_ARGS__) 
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern uint16_t aADCxConvertedData[7];
//extern uint8_t tx_uart1_buff_cmd[31];
//extern uint8_t tx_bms_10_buff[15];
extern uint8_t ac_rx_buff[24];
extern uint8_t ac_rx_cont;
extern uint8_t ac_rx_status;
extern uint8_t aa;
u8 Status_BUS;
u8 BAT_EN = 1;
uint16_t temp_v;
uint16_t temp_i;
uint16_t temp_ii;
uint16_t v_bat = 0;
uint16_t i_bat = 0;
int battery_cyc = 0;
u8 IB1_STATE;
u8 IB2_STATE;
u8 POWER_STATE = 0 ;
uint8_t bms_state = 0;
uint8_t ch_stade = 1;
uint8_t ch_stade1 = 1;
uint8_t bat_stade1 = 1;
uint8_t rx_usart1_cnt;
uint8_t rtu_buff1[30]={0};
uint8_t tx_len1 = 0;
uint8_t ModebusTxBuff[200];
//uint8_t udp_txbuff[200];
uint8_t ModebusRxBuff[128];
uint16_t rtu_buff[1090]={0};
uint8_t rx_usart3_cnt;
uint8_t ModebusTxBuff_M[128];
uint8_t ModebusRxBuff_M[128];
u8 bat_charge_indicator = 0;
u8 bat_discharge_indication = 0;
uint8_t proto = 0;
uint8_t rtu = 0;
MODEBUS_HANDLE ModebusHandle1;
MRTU_SLAVE_INFO FrameInfo1;	//modebus????

MODEBUS_HANDLE ModebusHandle2;
MRTU_SLAVE_INFO FrameInfo2;	//modebus????

uint16_t modbue_SlaveAddr = 1;
uint16_t udp_status =0;
int battery_capacity=0;
int SOH = 100;
int SOC = 50;
int battery_capacity_rate = 10000;
int battery_capacity_full = 0;
extern xQueueHandle xQueueRx_pc_uart1;
extern xQueueHandle xQueueRx_bms_uart2;
extern xQueueHandle xQueueRx_ac_uart3;

xSemaphoreHandle xSemaphoreRecf_pc_uart1;
xSemaphoreHandle xSemaphoreRecf_bms_uart2;
xSemaphoreHandle xSemaphoreRecf_ac_uart3;

uint32_t Voltage_Reg,Power_Reg,Voltage_Parameter_Reg,Power_Parameter_Reg,Current_Reg,Current_Parameter_Reg;
int16_t tem;
float ActivePower,ACVotage,ACCurrent;
uint32_t ac_v;
uint16_t ac_w;
uint16_t ac_i;

uint16_t out = 2;

float ac_v_f=0;
float ac_i_f=0;
float ac_w_f=0;

float battery_v = 0;
float battery_i=0;
float battery_i1=0;
float battery_i2=0;
float battery_i3=0;
float battery_c=3000;
float device_tem= 37.8;
u8 bat_state = 0;
u8 ctrl_1 = 0; //控制输出端口状态

uint8_t BAT_STATE1 = 1;
uint8_t out_lcd = 1;
uint16_t udp_rtu_con=0;
uint16_t modbue_Baud = 24;
//int battery_capacity_soh = 5;
uint16_t OUT1_266 = 0;
uint16_t OUT2_266 = 0;
uint16_t OUT3_266 = 0;
uint16_t OUT4_266 = 0;
uint16_t OUT5_266 = 0;
uint16_t OUT6_266 = 0;
uint16_t OUT7_266 = 0;
uint16_t OUT8_266 = 0;
uint16_t BAT_266 = 1;
uint16_t out_sum = 2;
uint16_t pcb_sum = 1;
uint16_t ctrl_2 = 0xffff;
uint16_t ctrl_3 = 0xffff;
uint16_t ctrl_4 = 0xffff;
uint16_t ctrl_5 = 0xffff;
uint8_t add = 1;
//uint16_t out = 3;
uint8_t m_s = 1;

float tempre =0;

int num_pic_battery =5;

int num_pic_bat_status =2;
uint16_t temp_v1[100]={0};
uint16_t temp_v2[100]={0};
uint16_t temp_v3[100]={0};
uint16_t temp_v4[100]={0};
uint16_t temp_v5[100]={0};
uint16_t temp_v6[100]={0};
uint16_t temp_v7[100]={0};

uint16_t temp_i1[100]={0};
uint16_t temp_i2[100]={0};
uint16_t temp_i3[100]={0};
uint16_t temp_i4[100]={0};
uint16_t temp_i5[100]={0};
uint16_t temp_i6[100]={0};
uint16_t temp_i7[100]={0};

float dc_v[13]={0};
float dc_i[13]={0};

uint8_t calibration_i;

uint8_t bms_add;

extern uint8_t adc_cont;

float v_k[13] ={1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
float i_k[13]={2.5,2.5,1.22,1.25,1.25,1.25,2.5,2.5,1.22,1.25,1.25,1.25,1.25};
float i_k_a[13]={1,1,1,1,1,1,1,1,1,1,1,1,1};

uint16_t t_adc[341]={123,131,139 ,148 ,157 ,167 ,178 ,189 ,200 ,212 ,225 ,239 ,253, 268 ,284 ,300 
,316 ,334 ,352 ,371 ,391 ,411 ,432 ,455 ,478 ,501 ,526 ,551 ,577 ,604 ,632 ,661 ,691 ,722 ,754 ,786 ,820 ,855 
,890 ,926 ,964 ,1000 ,1038 ,1077 ,1116 ,1156 ,1197 ,1238 ,1281 ,1323 ,1367 ,1410 ,1455 ,1499 ,1544 ,1590 ,1635 
,1681 ,1727 ,1773 ,1819 ,1865 ,1911 ,1957 ,2003 ,2048 ,2093 ,2138 ,2183 ,2227 ,2271 ,2314 ,2357 ,2399 ,2441 ,2482 
,2523 ,2562 ,2602 ,2640 ,2678 ,2716 ,2752 ,2788 ,2823 ,2857 ,2891 ,2924 ,2956 ,2988 ,3019 ,3049 ,3078 ,3106 ,3134 ,3161 ,3188 
,3214 ,3239 ,3263 ,3287 ,3310 ,3333 ,3355 ,3376 ,3397 ,3417 ,3437 ,3456 ,3474 ,3492 ,3510 ,3527 ,3543 ,3559 ,3575 ,3590 
,3604 ,3619 ,3632 ,3646 ,3659 ,3671 ,3684 ,3696 ,3707 ,3718 ,3729 ,3740 ,3750 ,3760 ,3770 ,3779 ,3788 ,3797 ,3806 ,3814 ,3822 
,3830 ,3837 ,3844 ,3851 ,3858 ,3865 ,3871 ,3877 ,3883 ,3889 ,3894 ,3900 ,3905 ,3910 ,3915 ,3920 ,3925 ,3929 ,3934 ,3938 ,3942 
,3946 ,3950 ,3954 ,3957 ,3961 ,3964 ,3968 ,3971 ,3974 ,3978 ,3981 ,3984 ,3987 ,3990 ,3993 ,3995 ,3998 ,4001 ,4003 ,4005 ,4008 
,4010 ,4012 ,4014 ,4016 ,4018 ,4020 ,4022 ,4024 ,4026 ,4027 ,4029 ,4031 ,4032 ,4034 ,4035 ,4036 ,4038 ,4039 ,4040 ,4042 ,4043 
,4044 ,4045 ,4046 ,4047 ,4048 ,4050 ,4051 ,4052 ,4052 ,4053 ,4054 ,4055 ,4056 ,4057 ,4058 ,4059 ,4059 ,4060 ,4061 ,4062 ,4063 
,4063 ,4064 ,4065 ,4065 ,4066 ,4067 ,4067 ,4068 ,4068 ,4069 ,4070 ,4070 ,4071 ,4071 ,4072 ,4072 ,4073 ,4073 ,4074 ,4074 ,4074 
,4075 ,4075 ,4076 ,4076 ,4076 ,4077 ,4077 ,4077 ,4078 ,4078 ,4078 ,4079 ,4079 ,4079 ,4080 ,4080 ,4080 ,4080 ,4081 ,4081 ,4081 
,4081 ,4082 ,4082 ,4082 ,4082 ,4083 ,4083 ,4083 ,4083 ,4084 ,4084 ,4084 ,4084 ,4085 ,4085 ,4085 ,4085 ,4085 ,4086 ,4086 ,4086 
,4086 ,4086 ,4086 ,4087 ,4087 ,4087 ,4087 ,4087 ,4087 ,4087 ,4088 ,4088 ,4088 ,4088 ,4088 ,4088 ,4088 ,4089 ,4089 ,4089 ,4089 
,4089 ,4089 ,4089 ,4089 ,4089 ,4089 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4090 ,4091 ,4091 ,4091 ,4091 
,4091 ,4091 ,4091 ,4091 ,4091 ,4091 ,4091 ,4091 ,4091 ,4092 ,4092 ,4092 ,4092 ,4092 
};

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */


uint32_t writeFlashData = 0x55555555;
uint32_t addr = 0x08010000; //// c8t6

/* I2C数据 - 9路INA226配置，地址从0x40开始连续排列*/
INA226_Dev dev1 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x40  // 第1路INA226地址
};

INA226_Dev dev2 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x41  // 第2路INA226地址
};

INA226_Dev dev3 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x42  // 第3路INA226地址
};

INA226_Dev dev4 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x43  // 第4路INA226地址
};

INA226_Dev dev5 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x44  // 第5路INA226地址
};

INA226_Dev dev6 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x45  // 第6路INA226地址
};

INA226_Dev dev7 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x46  // 第7路INA226地址
};

INA226_Dev dev8 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x47  // 第8路INA226地址
};

INA226_Dev dev9 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,    // 采样电阻值
    .max_current = 3.2768f,  // 最大电流
    .addr = 0x48  // 第9路INA226地址
};

//FLASH写入数据测试
void writeFlashTest(void)
{
	//1、解锁FLASH
  HAL_FLASH_Unlock();
	
	//2、擦除FLASH
	//初始化FLASH_EraseInitTypeDef
	FLASH_EraseInitTypeDef f;
	f.TypeErase = FLASH_TYPEERASE_PAGES;
	f.PageAddress = addr;
	f.NbPages = 1;
	//设置PageError
	uint32_t PageError = 0;
	uint8_t i;
	//调用擦除函数
	HAL_FLASHEx_Erase(&f, &PageError);

	//3、对FLASH烧写
		for (i =0;i<=12;i++){
	HAL_FLASH_Program(0x02U, addr+4*i, (uint32_t)(v_k[i]*100));
	}
	for (i =0;i<=12;i++){
	HAL_FLASH_Program(0x02U, addr+4*(i+13), (uint32_t)(i_k[i]*100));
	}
	
	
	HAL_FLASH_Program(0x02U, addr+26*4, (uint32_t)(modbue_SlaveAddr));
	HAL_FLASH_Program(0x02U, addr+27*4, (uint32_t)(udp_status));
	
	for (i =0;i<=12;i++){
	HAL_FLASH_Program(0x02U, addr+4*(i+28), (uint32_t)(i_k_a[i]*100));
	}
	HAL_FLASH_Program(0x02U, addr+41*4, (uint32_t)(modbue_Baud));
	HAL_FLASH_Program(0x02U, addr+42*4, (uint32_t)(SOH));
	HAL_FLASH_Program(0x02U, addr+43*4, (uint32_t)(battery_cyc));
	HAL_FLASH_Program(0x02U, addr+44*4, (uint32_t)(SOC));
	//4¡¢˸סFLASH
	
	
	//4����סFLASH
	
	rtu_buff[6] = modbue_SlaveAddr;
	rtu_buff[154] = udp_status;
	rtu_buff[4] = modbue_Baud;
	rtu_buff[5] = SOH;
	rtu_buff[7] = battery_cyc;
	rtu_buff[130] = SOC;
   HAL_FLASH_Lock();
}

//FLASH读取数据测试
void printFlashTest(void)
{
uint8_t i;
	
		if(((uint16_t) *(__IO uint32_t*)(addr))>=0xffff){
	writeFlashTest();	
	}
	
	for(i=0;i<=12;i++){
	v_k[i] =((float) *(__IO uint32_t*)(addr+4*i)/100.00);
	}

	
	for(i=0;i<=12;i++){
	i_k[i] =((float) *(__IO uint32_t*)(addr+4*(i+13))/100.00);
	}
	modbue_SlaveAddr = ((uint8_t) *(__IO uint32_t*)(addr+26*4));
	udp_status = ((uint16_t) *(__IO uint32_t*)(addr+27*4));	
	
	
	for(i=0;i<=12;i++){
	i_k_a[i] =((float) *(__IO uint32_t*)(addr+4*(i+28))/100.00);
	}
	modbue_Baud = ((uint16_t) *(__IO uint32_t*)(addr+41*4));
	SOH = ((uint16_t) *(__IO uint32_t*)(addr+42*4));	
	battery_cyc = ((uint16_t) *(__IO uint32_t*)(addr+43*4));	
	SOC = ((uint16_t) *(__IO uint32_t*)(addr+44*4));	
	rtu_buff[6] = modbue_SlaveAddr;
	rtu_buff[154] = udp_status;
	rtu_buff[4] = modbue_Baud;
	rtu_buff[5] = SOH;
	rtu_buff[7] = battery_cyc;
	rtu_buff[130] = SOC;
}


/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for myLCD_Task */
osThreadId_t myLCD_TaskHandle;
const osThreadAttr_t myLCD_Task_attributes = {
  .name = "myLCD_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow7,
};
/* Definitions for modbus_rtu */
osThreadId_t modbus_rtuHandle;
const osThreadAttr_t modbus_rtu_attributes = {
  .name = "modbus_rtu",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for myled_Task */
osThreadId_t myled_TaskHandle;
const osThreadAttr_t myled_Task_attributes = {
  .name = "myled_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for mybms_task */
osThreadId_t mybms_taskHandle;
const osThreadAttr_t mybms_task_attributes = {
  .name = "mybms_task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */


//////////  adc
osThreadId_t TC_TaskHandle;
const osThreadAttr_t TC_Task_attributes = {
  .name = "TC_Task",
  .priority = (osPriority_t) osPriorityHigh,
  .stack_size = 128 * 4
};
  

void Start_TC_Task(void *argument);

///////////////////////////////////////   pc cmd

osThreadId_t cmd_TaskHandle;
const osThreadAttr_t cmd_Task_attributes = {
  .name = "cmd_Task",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
  

void Start_cmd_Task(void *argument);

///////  bms

osThreadId_t bms_TaskHandle;



/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);
void StartLCD_Task(void *argument);
void Startmodbus_rtu(void *argument);
void Startled_Task(void *argument);
void Startbms_Task(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
       
  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* creation of myLCD_Task */
  myLCD_TaskHandle = osThreadNew(StartLCD_Task, NULL, &myLCD_Task_attributes);

  /* creation of modbus_rtu */
  modbus_rtuHandle = osThreadNew(Startmodbus_rtu, NULL, &modbus_rtu_attributes);

  /* creation of myled_Task */
  myled_TaskHandle = osThreadNew(Startled_Task, NULL, &myled_Task_attributes);

  /* creation of mybms_task */
  mybms_taskHandle = osThreadNew(Startbms_Task, NULL, &mybms_task_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  
  
  TC_TaskHandle= osThreadNew(Start_TC_Task, NULL, &TC_Task_attributes);
  
  
  cmd_TaskHandle= osThreadNew(Start_cmd_Task, NULL, &cmd_Task_attributes);
  
  

  //frequencyTaskHandle = osThreadNew(StartFrequencyTask, NULL, &frequencyTask_attributes);
  
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	
	uint8_t temp;
	
	
	
	 MODEBUS_slave_Init(&ModebusHandle1, 01, modbue_Baud*100, ModebusRxBuff, ModebusTxBuff, 128-1, 200);
	
	 LL_TIM_ClearFlag_UPDATE(TIM1);
	 //LL_TIM_ClearFlag_UPDATE(TIM3);
	
	 LL_TIM_EnableIT_UPDATE(TIM1);
   
	
	
	
	 // LL_TIM_EnableIT_UPDATE(TIM3);
   LL_TIM_EnableCounter(TIM3);
	
	
  LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_1,1);
	
  LL_DMA_SetPeriphAddress(DMA1,LL_DMA_CHANNEL_1,LL_ADC_DMA_GetRegAddr(ADC1,LL_ADC_DMA_REG_REGULAR_DATA));
 
  LL_DMA_SetMemoryAddress(DMA1,LL_DMA_CHANNEL_1,(uint32_t)aADCxConvertedData);
 
  LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_1);
	
	LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_1);
	
	
	
	LL_ADC_Enable(ADC1);
	 
	LL_ADC_StartCalibration(ADC1);
 
  while( LL_ADC_IsCalibrationOnGoing(ADC1));
	
  LL_ADC_REG_SetDMATransfer(ADC1,LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
 
  
      temp =((uint8_t) *(__IO uint32_t*)(addr));

	if(temp == 0xff){
	
	writeFlashTest();
	}
	else{
	printFlashTest();}
	
	osDelay(2000);	
  /* Infinite loop */
  for(;;)
  {    	    
	LL_GPIO_ResetOutputPin(RUN_LED_GPIO_Port,RUN_LED_Pin);
	osDelay(500);
	LL_GPIO_SetOutputPin(RUN_LED_GPIO_Port,RUN_LED_Pin);
	osDelay(500);	    	   
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_StartLCD_Task */
/**
* @brief Function implementing the myLCD_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartLCD_Task */
void StartLCD_Task(void *argument)
{
  /* USER CODE BEGIN StartLCD_Task */
  /* Infinite loop */
  /*LCD显示*/
	osDelay(2000);	  
	for(;;)
  {				
		osDelay(200); 
	}

  /* USER CODE END StartLCD_Task */
}

/* USER CODE BEGIN Header_Startmodbus_rtu */
/**
* @brief Function implementing the modbus_rtu thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Startmodbus_rtu */
void Startmodbus_rtu(void *argument)
{
  /* USER CODE BEGIN Startmodbus_rtu */
  /* Infinite loop */
	/*MODEBUS_RTU响应*/
	
u16 data;
	u16 RegBuff[128];
	u8 i;
	u32 cnt1 = 0,cnt2 = 0;
	u8 Fun;

	for(i = 0;i < 10;i ++)
	{
		RegBuff[i] = i+1;
	}
	
	for(;;)
	{
		if(rtu){
			rtu = 0;
		cnt2 = cnt1;
	//	cnt1 = MODEBUS_GetDataCnt(ModebusHandle1.UartCh);
		
		cnt1 = rx_usart1_cnt;
		rx_usart1_cnt = 0 ;
	//	if((cnt1 == cnt2) && (cnt1 != 0))
   if( cnt1 != 0)
		{
			LL_USART_DisableIT_RXNE(USART1);
			if(MODEBUS_SLAVE_FramesUnpack(&ModebusHandle1, modbue_SlaveAddr, cnt1, &Fun) == MRTU_OK)
			{
				//usb_printf("接收功能码:0x%02X\r\n", Fun);
				switch(Fun)
				{
					case MRTU_FUN_READ_HOLD		:				// 3
				//	case MRTU_FUN_READ_INPUT	:					// 4 
					{
						//解析请求
						MODEBUS_SLAVE_ReadUnpack(&ModebusHandle1, &FrameInfo1);
						//准备响应数据
						//usb_printf("读取请求(从站:%d)从%d寄存器开始,读取%d个寄存器\r\n", FrameInfo1.SlaveAddr,  FrameInfo1.StartReg, FrameInfo1.RegNum);
						//发送响应
						
						
						MODEBUS_SLAVE_ReturnReadReg(&ModebusHandle1, FrameInfo1.fun, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, FrameInfo1.RegNum, rtu_buff);
						
//						else {
//						
//						 MODEBUS_HOST_ReadMultReg(&ModebusHandle2, 3 , 1, FrameInfo1.StartReg,FrameInfo1.RegNum,RegBuff);
//						 MODEBUS_SLAVE_ReturnReadReg(&ModebusHandle1, FrameInfo1.fun, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, FrameInfo1.RegNum, RegBuff);	
//						}
						
						}break;
					
					case MRTU_FUN_WRITE			:					//6
					{
						//??
						MODEBUS_SLAVE_WriteUnpack(&ModebusHandle1, &FrameInfo1, &data);
						//????
						//usb_printf("?????(%d)????%d??:0x%02X\r\n", FrameInfo1.SlaveAddr,  FrameInfo1.StartReg, data);
						//??
						//rtu_buff[FrameInfo1.StartReg] = data;
						
						calibration_i =1;
						MODEBUS_SLAVE_ReturnWriteHoldReg(&ModebusHandle1, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, data);
					}break;
					case MRTU_FUN_MWRITE		:					//10
					{
						//??
						MODEBUS_SLAVE_WriteMultUnpack(&ModebusHandle1, &FrameInfo1, RegBuff);
						//????
//						usb_printf("?????(%d),?%d??????,?%d?,???:", FrameInfo1.SlaveAddr,  FrameInfo1.StartReg, FrameInfo1.RegNum);
//						for(i = 0;i < FrameInfo1.RegNum;i ++)
//						{
//							usb_printf("0x%04X ", RegBuff[i]);	//????
//						}
//						usb_printf("\r\n");
						//??
						if(FrameInfo1.StartReg<0x800){
							memcpy(rtu_buff+ FrameInfo1.StartReg,RegBuff,FrameInfo1.RegNum*2);
						//memcpy(rtu_buff,RegBuff,2);
							MODEBUS_SLAVE_ReturnWriteMultHoldReg(&ModebusHandle1, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, FrameInfo1.RegNum);
						}
						else{
							   
							if(RegBuff[0] ==0xaaaa)
							{
							v_k[(RegBuff[1]-1)]=v_k[(RegBuff[1]-1)]* (((float)RegBuff[2] /100.00)/dc_v[(RegBuff[1]-1)]);			
						//	v_k[1]=v_k[1]* (((float)RegBuff[3] /100.00)/dc_v[1]);					
						//	v_k[2]=v_k[2]* (((float)RegBuff[4] /100.00)/dc_v[12]);									
							writeFlashTest();	
							}
							
							if(RegBuff[0] ==0xbbbb)
							{
						   if(dc_i[(RegBuff[1]-1)] > 0){
								 i_k_a[(RegBuff[1]-1)]=i_k_a[(RegBuff[1]-1)]*(((float)RegBuff[2] /100.00)/dc_i[(RegBuff[1]-1)]);		
						  //  i_k_a[1]=i_k_a[1]*(((float)RegBuff[3] /100.00)/dc_i[1]);	
						  //  i_k_a[2]=i_k_a[2]*(((float)RegBuff[4] /100.00)/dc_i[12]);	
								 }	
               if(dc_i[(RegBuff[1]-1)] < 0){
								 i_k_a[(RegBuff[1]-1)]=i_k_a[(RegBuff[1]-1)]*(((float)RegBuff[2] /100.00)/(-dc_i[(RegBuff[1]-1)]));		
						  //  i_k_a[1]=i_k_a[1]*(((float)RegBuff[3] /100.00)/dc_i[1]);	
						  //  i_k_a[2]=i_k_a[2]*(((float)RegBuff[4] /100.00)/dc_i[12]);	
								 }									 
							writeFlashTest();	
							}
							
								MODEBUS_SLAVE_ReturnWriteMultHoldReg(&ModebusHandle1, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, FrameInfo1.RegNum);
							}
//						}
						
						}break;
					
					
					case MRTU_FUN_WRITE_ADD		:					//11
					{
						//??
						MODEBUS_SLAVE_WriteUnpack(&ModebusHandle1, &FrameInfo1, &data);
						
						//????
						//usb_printf("?????(%d)????%d??:0x%02X\r\n", FrameInfo1.SlaveAddr,  FrameInfo1.StartReg, data);
				       
						//??
						MODEBUS_SLAVE_ReturnWrite_add(&ModebusHandle1, FrameInfo1.SlaveAddr, FrameInfo1.StartReg, data); //
					}break;
					default:break;
				}
				
			}
			//MODEBUS_EnableRx(ModebusHandle1.UartCh);	//????
			 LL_USART_EnableIT_RXNE(USART1);
		}
	
		//OSTimeDlyHMSM(0,0,0,200);
		osDelay(100);
	}	
}
  /* USER CODE END Startmodbus_rtu */
}

/* USER CODE BEGIN Header_Startled_Task */
/**
* @brief Function implementing the myled_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Startled_Task */
void Startled_Task(void *argument)
{
  /* USER CODE BEGIN Startled_Task */
  /* Infinite loop */
	/*UDP自动上传数据*/
	
  for(;;)
  {
		
		 if(udp_status == 1)  {
			 
     MODEBUS_SLAVE_ReturnReadReg(&ModebusHandle1, 03, modbue_SlaveAddr, 128, 98, rtu_buff);
			 
		 }   
			osDelay(3000);
  }
  /* USER CODE END Startled_Task */
}

/* USER CODE BEGIN Header_Startbms_Task */
/**
* @brief Function implementing the mybms_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Startbms_Task */
void Startbms_Task(void *argument)
{
  /* USER CODE BEGIN Startbms_Task */
  /* Infinite loop */
	/*电池管理任务*/
	u8 aaa = 0;
	u8 bat_disch_counter = 0; 
	osDelay(2000);
    // 计算电池容量百分比
    battery_capacity = (SOC * 100) / battery_capacity_rate;          	
  for(;;)
  {     								
    // 充电逻辑处理
    if(battery_i <= -0.05f)  // 检测到充电电流
    {
      // 更新SOC值 (根据电流计算容量变化)
      battery_capacity += (-battery_i * 1000.0f) / 3600.0f;
      
      // 检查是否充满电或达到最高电压
      if(battery_capacity >= battery_capacity_rate || 
         battery_v >= (rtu_buff[137] * 3.65f))
      {
        battery_capacity = battery_capacity_rate; // 充满电
        bat_charge_indicator = 1;                // 充电指示
      }
    }
    
    // 放电逻辑处理
    if(battery_i >= 0.05f)  // 检测到放电电流
    {
      // 更新SOC值 (根据电流计算容量变化)
      battery_capacity -= (battery_i * 1000.0f) / 3600.0f;
      
      // 低电量指示
      if(battery_capacity <= 1000)
      {
        bat_discharge_indication = 1;
      }
    }
    
    // 电压保护逻辑 - 统一处理
    // 高电压保护 (充满保护)
    if(battery_v >= (rtu_buff[137] * 3.65f))
    {
      battery_capacity = battery_capacity_rate;
      bat_charge_indicator = 1;
    }
    // 低电压保护 (过放保护)
    if(battery_v <= (rtu_buff[137] * 2.7f))
    {
      bat_disch_counter++;
      // 防抖动处理，连续检测到低电压才触发保护
      if(bat_disch_counter >= 4)
      {
        battery_capacity = 0; // 强制设为0
        bat_disch_counter = 0;    // 重置计数器
      }
    }
    else
    {
      bat_disch_counter = 0; // 电压正常时重置计数器
    }       
    if(battery_capacity > battery_capacity_rate)
    {
      battery_capacity = battery_capacity_rate;
    }    
    // 重新计算并更新电池容量百分比
    SOC = (battery_capacity * 100) / battery_capacity_rate;
    if(BAT_STATE1 == 0){
		SOC = 0;
		battery_capacity = 0;
	}
	// 边界检查 - 确保SOC在有效范围内
    if(SOC < 0)
    {
      SOC = 0;
    }
	rtu_buff[130] = SOC;
	rtu_buff[131] = SOH;
	rtu_buff[132] = battery_capacity;
	rtu_buff[133] = battery_capacity_full;
	rtu_buff[134] = battery_capacity_rate;
	rtu_buff[135] = battery_cyc;
	rtu_buff[137] = 6;	
		// 先关闭所有电量LED（不包括POW_LED，因为它是其他功能指示）
		LL_GPIO_SetOutputPin(POW20_LED_GPIO_Port, POW20_LED_Pin);
		LL_GPIO_SetOutputPin(POW40_LED_GPIO_Port, POW40_LED_Pin);
		LL_GPIO_SetOutputPin(POW60_LED_GPIO_Port, POW60_LED_Pin);
		LL_GPIO_SetOutputPin(POW80_LED_GPIO_Port, POW80_LED_Pin);
		
		// 根据SOC值点亮相应的LED
		if(BAT_STATE1 == 1){					
		if (SOC >= 10)
		{
			// SOC >= 20% 点亮20% LED
			if (SOC >= 20)
			{
				LL_GPIO_ResetOutputPin(POW20_LED_GPIO_Port, POW20_LED_Pin);
				
				// SOC >= 40% 点亮40% LED
				if (SOC >= 40)
				{
					LL_GPIO_ResetOutputPin(POW40_LED_GPIO_Port, POW40_LED_Pin);
					
					// SOC >= 60% 点亮60% LED
					if (SOC >= 60)
					{
						LL_GPIO_ResetOutputPin(POW60_LED_GPIO_Port, POW60_LED_Pin);
						
						// SOC >= 80% 点亮80% LED
						if (SOC >= 80)
						{
							LL_GPIO_ResetOutputPin(POW80_LED_GPIO_Port, POW80_LED_Pin);
						}
					}
				}
			}
		}
	}else{
		if(aaa == 1){
		LL_GPIO_SetOutputPin(POW20_LED_GPIO_Port, POW20_LED_Pin);
		LL_GPIO_SetOutputPin(POW40_LED_GPIO_Port, POW40_LED_Pin);
		LL_GPIO_SetOutputPin(POW60_LED_GPIO_Port, POW60_LED_Pin);
		LL_GPIO_SetOutputPin(POW80_LED_GPIO_Port, POW80_LED_Pin);
		aaa = 0;	
		}else{
			LL_GPIO_ResetOutputPin(POW20_LED_GPIO_Port, POW20_LED_Pin);
			LL_GPIO_ResetOutputPin(POW40_LED_GPIO_Port, POW40_LED_Pin);
			LL_GPIO_ResetOutputPin(POW60_LED_GPIO_Port, POW60_LED_Pin);
			LL_GPIO_ResetOutputPin(POW80_LED_GPIO_Port, POW80_LED_Pin);
			aaa = 1;
		}
	}
    osDelay(1000);
	
  }
  /* USER CODE END Startbms_Task */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void Start_TC_Task(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	/*信息测量*/
	uint32_t  v,i;
	uint16_t v_max,i_max,i_min;
	uint16_t v_min;
	u16 data;
	int16_t RegBuff[30];
//	u8 i;
	u8 cont;
	u32 cnt1 = 0,cnt2 = 0;
	u8 Fun;
	u16  pRegData;
	u8 ii1 = 0;
	u8 ii2 = 0;
	u8 ii3 = 0; 
	uint16_t  ctrl = 0;
	uint16_t temp;
	uint8_t dianliu;
	uint16_t sum =0;
  uint8_t cheaksum,a;
	float reg;
	float temp_float;
  float temp_a;
	float bus_v, current, shunt_v;
	rtu_buff[199] = 0xD2;
  uint8_t res;
	uint8_t out_sum_temp = 0;
	// 错误计数变量，用于跟踪I2C通信状态
	uint8_t i2c_error_counts[9] = {0}; // 9路INA226的错误计数
	uint32_t last_recovery_time = 0;    // 上次总线恢复时间戳
	 LL_USART_EnableIT_RXNE(USART2);	 
	 LL_USART_EnableIT_IDLE(USART2);	 
	 LL_USART_EnableDMAReq_TX(USART1);	 
	 LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_4, (uint32_t)ModebusTxBuff);
   LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_4, (uint32_t)(&USART1->DR));
   LL_USART_EnableIT_RXNE(USART1); 	
	 LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_4);
   calibration_i =0;
	 LL_mDelay(200);
	 
   /* 初始化9路INA226 */
    // 第1路INA226初始化
    if(INA226_Init(&dev1) != INA226_OK) {
       OUT1_266 = 0;
		}
    else{OUT1_266 = 1;}                
    
    // 第2路INA226初始化
    if(INA226_Init(&dev2) != INA226_OK) {
       OUT2_266 = 0;
		}
    else{OUT2_266 = 1;}
	
    // 第3路INA226初始化
    if(INA226_Init(&dev3) != INA226_OK) {
       OUT3_266 = 0;            
    }else{OUT3_266 = 1;}
    
    // 第4路INA226初始化
    if(INA226_Init(&dev4) != INA226_OK) {
       OUT4_266 = 0;            
    }else{OUT4_266 = 1;}
    
    // 第5路INA226初始化
    if(INA226_Init(&dev5) != INA226_OK) {
       OUT5_266 = 0;            
    }else{OUT5_266 = 1;}
    
    // 第6路INA226初始化
    if(INA226_Init(&dev6) != INA226_OK) {
       OUT6_266 = 0;            
    }else{OUT6_266 = 1;}
    
    // 第7路INA226初始化
    if(INA226_Init(&dev7) != INA226_OK) {
       OUT7_266 = 0;            
    }else{OUT7_266 = 1;}
    
    // 第8路INA226初始化
    if(INA226_Init(&dev8) != INA226_OK) {
       OUT8_266 = 0;            
    }else{OUT8_266 = 1;}
    
    // 第9路INA226初始化
    if(INA226_Init(&dev9) != INA226_OK) {
       BAT_266 = 0;            
    }else{BAT_266 = 1;}
	 	
  /* Infinite loop */
  for(;;)
  { 
		
		
		if(calibration_i ==1 ){
		
		calibration_i =0;
			
//		i_k[0] = (float)(((aADCxConvertedData[11])*3300.0/4096.0/1000)*1.515);
//		i_k[1] = (float)(((aADCxConvertedData[1])*3300.0/4096.0/1000)*1.515);
//		i_k[2] = (float)(((aADCxConvertedData[3])*3300.0/4096.0/1000)*1.515);
//		i_k[3] = (float)(((aADCxConvertedData[0])*3300.0/4096.0/1000)*2.87);
//		i_k[4] = (float)(((aADCxConvertedData[2])*3300.0/4096.0/1000)*2.87);
//		i_k[5] = (float)((aADCxConvertedData[5])*3300.0/4096.0/1000);	
//		i_k[6] = (float)((aADCxConvertedData[5])*3300.0/4096.0/1000);
//		i_k[7] = (float)(((aADCxConvertedData[2])*3300.0/4096.0/1000)*2.87);
//		i_k[8] = (float)((aADCxConvertedData[5])*3300.0/4096.0/1000);	
//		i_k[9] = (float)((aADCxConvertedData[5])*3300.0/4096.0/1000);
	writeFlashTest();			

		}
		if(calibration_i ==2 ){
		
		calibration_i =0;
//		i_k[4] = (float)(((aADCxConvertedData[1])*3300.0/4096.0/1000)*1.515);
//		i_k[3] = (float)(((aADCxConvertedData[3])*3300.0/4096.0/1000)*1.515);
//		i_k[2] = (float)(((aADCxConvertedData[5])*3300.0/4096.0/1000)*1.515);
//		i_k[1] = (float)(((aADCxConvertedData[7])*3300.0/4096.0/1000)*1.515);
//		i_k[0] = (float)(((aADCxConvertedData[9])*3300.0/4096.0/1000)*1.515);			
			
		writeFlashTest();	
		
		}
	   //////////////////////////		
			
			
			/*温度测量*/
		 for(tem=0;tem<340;tem++)
    {
		 if( t_adc[tem]>aADCxConvertedData[0])
		 break;
		}
	tem = (tem-40)*10;
   	rtu_buff[138] = tem;
	// printf("dianliu = %d \n",(tem);			
	device_tem = (float )tem/10.00;
		
		/*读取9路INA226数据并存储到对应数组位置*/
		// 定期检查并恢复I2C总线（每100ms最多一次）
		uint32_t current_time = HAL_GetTick();
		if((current_time - last_recovery_time > 100)) {
			// 计算错误率
			uint8_t total_errors = 0;
			for(uint8_t i = 0; i < 9; i++) {
				total_errors += i2c_error_counts[i];
			}
			
			// 如果错误率较高，尝试在读取前恢复总线
			if(total_errors > 5) {
				// 创建临时设备结构用于总线恢复
				INA226_Dev temp_dev;
				temp_dev.scl_port = I2C_SCL_GPIO_Port;
				temp_dev.scl_pin = I2C_SCL_Pin;
				temp_dev.sda_port = I2C_SDA_GPIO_Port;
				temp_dev.sda_pin = I2C_SDA_Pin;
				
				// 调用读取函数来触发内部恢复机制
				INA226_ReadAll(&temp_dev, &bus_v, &current, &shunt_v);
				
				// 重置错误计数
				for(uint8_t i = 0; i < 9; i++) {
					i2c_error_counts[i] = 0;
				}
				
				last_recovery_time = current_time;
			}
		}
		
		float bus_v, current, shunt_v;
		uint8_t res;
		
		// 第1路INA226 - 存储到dc_v[0], dc_i[0]
        res = INA226_ReadAll(&dev1, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[0] = bus_v * v_k[0];
			dc_i[0] = current * i_k_a[0] / 1.05;
			i2c_error_counts[0] = 0; // 重置错误计数
        } else {
			i2c_error_counts[0]++; // 增加错误计数
			// 保留上次有效数据，不再重试以减少被中断风险
        }
        rtu_buff[157] = (uint16_t)(dc_v[0] * 100);
        rtu_buff[158] = (uint16_t)(dc_i[0] * 100);
      //u_buff[164] = (uint16_t)(dc_i[0] * 1000);
		// 第2路INA226 - 存储到dc_v[1], dc_i[1]
        res = INA226_ReadAll(&dev2, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[1] = bus_v * v_k[1];
			dc_i[1] = current * i_k_a[1] * 1.05;
			i2c_error_counts[1] = 0; // 重置错误计数
        } else {
			i2c_error_counts[1]++; // 增加错误计数
			// 保留上次有效数据
        }
        rtu_buff[159] = (uint16_t)(dc_v[1] * 100);
        rtu_buff[160] = (uint16_t)(dc_i[1] * 100);
		// 第3路INA226 - 存储到dc_v[2], dc_i[2]
        res = INA226_ReadAll(&dev3, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[2] = bus_v * v_k[2];
			dc_i[2] = current * i_k_a[2];
			i2c_error_counts[2] = 0; // 重置错误计数
        } else {
			i2c_error_counts[2]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第4路INA226 - 存储到dc_v[3], dc_i[3]
        res = INA226_ReadAll(&dev4, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[3] = bus_v * v_k[3];
			dc_i[3] = current * i_k_a[3];
			i2c_error_counts[3] = 0; // 重置错误计数
        } else {
			i2c_error_counts[3]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第5路INA226 - 存储到dc_v[4], dc_i[4]
        res = INA226_ReadAll(&dev5, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[4] = bus_v * v_k[4];
			dc_i[4] = current * i_k_a[4];
			i2c_error_counts[4] = 0; // 重置错误计数
        } else {
			i2c_error_counts[4]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第6路INA226 - 存储到dc_v[5], dc_i[5]
        res = INA226_ReadAll(&dev6, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[5] = bus_v * v_k[5];
			dc_i[5] = current * i_k_a[5];
			i2c_error_counts[5] = 0; // 重置错误计数
        } else {
			i2c_error_counts[5]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第7路INA226 - 存储到dc_v[6], dc_i[6]
        res = INA226_ReadAll(&dev7, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[6] = bus_v * v_k[6];
			dc_i[6] = current * i_k_a[6];
			i2c_error_counts[6] = 0; // 重置错误计数
        } else {
			i2c_error_counts[6]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第8路INA226 - 存储到dc_v[7], dc_i[7]
        res = INA226_ReadAll(&dev8, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[7] = bus_v * v_k[7];
			dc_i[7] = current * i_k_a[7];
			i2c_error_counts[7] = 0; // 重置错误计数
        } else {
			i2c_error_counts[7]++; // 增加错误计数
			// 保留上次有效数据
        }		
		// 第9路INA226 - 存储到dc_v[12], dc_i[12]
        res = INA226_ReadAll(&dev9, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[12] = bus_v * v_k[12];
			dc_i[12] = current * i_k_a[12]*3 / 1.05;
			i2c_error_counts[8] = 0; // 重置错误计数
        } else {
			i2c_error_counts[8]++; // 增加错误计数
			// 保留上次有效数据
        }
		// 所有读取完成后进行一次适度延迟，让出CPU资源
		osDelay(30);

		 ///////////////////////////////////
            // 第3路电压电流
			rtu_buff[161] = (uint16_t)(dc_v[2] * 100);
			rtu_buff[162] = (uint16_t)(dc_i[2] * 100);
			
			// 第4路电压电流
			rtu_buff[163] = (uint16_t)(dc_v[3] * 100);
			rtu_buff[164] = (uint16_t)(dc_i[3] * 100);
			
			// 第5路电压电流
			rtu_buff[165] = (uint16_t)(dc_v[4] * 100);
			rtu_buff[166] = (uint16_t)(dc_i[4] * 100);
			
			// 第6路电压电流
			rtu_buff[167] = (uint16_t)(dc_v[5] * 100);
			rtu_buff[168] = (uint16_t)(dc_i[5] * 100);
			
			// 第7路电压电流
			rtu_buff[169] = (uint16_t)(dc_v[6] * 100);
			rtu_buff[170] = (uint16_t)(dc_i[6] * 100); 
			
			// 第8路电压电流
			rtu_buff[171] = (uint16_t)(dc_v[7] * 100);
			rtu_buff[172] = (uint16_t)(dc_i[7] * 100);
				
			battery_v = dc_v[12];
			battery_i = dc_i[12];
			rtu_buff[128] = (int16_t)(battery_i*100);
			rtu_buff[129] = (uint16_t)(dc_v[12]*100);
				
		if(battery_i < -0.1){                                                                                                                               
		num_pic_bat_status = 3;
		LL_GPIO_ResetOutputPin(CH_LED_GPIO_Port,CH_LED_Pin);
		}else{LL_GPIO_SetOutputPin(CH_LED_GPIO_Port,CH_LED_Pin);}

		if(battery_i > 0.1){
			num_pic_bat_status = 2;
			LL_GPIO_ResetOutputPin(FL_LED_GPIO_Port,FL_LED_Pin); 
		}else{LL_GPIO_SetOutputPin(FL_LED_GPIO_Port,FL_LED_Pin);}

		if((battery_i >= -0.1) & (battery_i <= 0.1)){
			num_pic_bat_status = 4;
		}
		if((battery_i >= -0.1) & (battery_i <= 0.1)){
			ch_stade = 0;
			LL_GPIO_ResetOutputPin(EN_CH_GPIO_Port,EN_CH_Pin); // 关闭电池充电
            osDelay(1500);
			res = INA226_ReadAll(&dev9, &bus_v, &current, &shunt_v);
        if(res == INA226_OK) {
			dc_v[12] = bus_v * v_k[12];
			dc_i[12] = current * i_k_a[12]*3 / 1.05;
			i2c_error_counts[8] = 0; // 重置错误计数
        } else {
			i2c_error_counts[8]++; // 增加错误计数
			// 保留上次有效数据
        }
		if(dc_v[12] > 12){
			BAT_STATE1 = 1; 
		}else{
			BAT_STATE1 = 0;
		}
		ch_stade = 1;
	                                                 }
	
		if(SOC <= 20){
			num_pic_battery = 5;
		}else if (SOC <= 40){
			num_pic_battery = 4;
		}else if (SOC <= 60){
			num_pic_battery = 3;
		}else if (SOC <= 80){
			num_pic_battery = 2;
		}else {
			num_pic_battery = 1;
		}
		
		///////////////////////////
		
		/*告警状态信息*/
		rtu_buff[140] = 5; //设备固件版本
		rtu_buff[151] = modbue_SlaveAddr;  //485地址
		rtu_buff[152] = modbue_Baud;  //485波特率 
		rtu_buff[156] = 8;  //输出路数 			 			 				 
		
		// 136寄存器定义（电源告警寄存器）
		// 位0（0x0001）: AC电源状态 - 0=正常，1=异常（PG引脚检测）
		// 位1（0x0002）: 电量告警 - 1=电池容量≤20%，0=电池容量>20%
		// 位2（0x0004）: 高温告警 - 1=设备温度≥50℃，0=设备温度<50℃
		// 位3（0x0008）: 低温告警 - 1=设备温度≤-20℃，0=设备温度>-20℃
		// 位4（0x0010）: 第1路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位5（0x0020）: 第2路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位6（0x0040）: 第3路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位7（0x0080）: 第4路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位8（0x0100）: 第5路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位9（0x0200）: 第6路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位10（0x0400）: 第7路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位11（0x0800）: 第8路输出电压告警 - 1=电压≤20V，0=电压>20V
		// 位12-15: 预留未使用
		
		ctrl = rtu_buff[136]; // 获取当前告警状态
		
		/*AC电源状态检测*/
		if(!LL_GPIO_IsInputPinSet(PG_GPIO_Port,PG_Pin)){        
			rtu_buff[136] = (ctrl & 0XFFFE); // 清除位0，表示AC电源正常
			POWER_STATE = 1;
			LL_GPIO_ResetOutputPin(POW_LED_GPIO_Port,POW_LED_Pin);
		}
		else {
			rtu_buff[136] = (ctrl | 0X0001); // 设置位0，表示AC电源异常
			POWER_STATE = 0;
			LL_GPIO_SetOutputPin(POW_LED_GPIO_Port,POW_LED_Pin);
		}
		ctrl = rtu_buff[136];
		
		/*电量告警检测*/
		if(SOC <= 20){
			rtu_buff[136] = (ctrl | 0X0002); // 设置位1，表示电量低
		}else{
			rtu_buff[136] = (ctrl & 0XFFFD); // 清除位1，表示电量正常
		}
		ctrl = rtu_buff[136];
		
		/*高温告警检测*/
		if(device_tem >= 50){
			rtu_buff[136] = (ctrl | 0X0004); // 设置位2，表示高温
		}else{
			rtu_buff[136] = (ctrl & 0XFFFB); // 清除位2，表示温度正常
		}
		ctrl = rtu_buff[136];
		
		/*低温告警检测*/
		if(device_tem <= -20){
			rtu_buff[136] = (ctrl | 0X0008); // 设置位3，表示低温
		}else{
			rtu_buff[136] = (ctrl & 0XFFF7); // 清除位3，表示温度正常
		}
		ctrl = rtu_buff[136];
		
		/*第1路输出电压告警检测*/
		if(dc_v[0] <= 20){
			rtu_buff[136] = (ctrl | 0X0010); // 设置位4，表示第1路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFEF); // 清除位4，表示第1路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第2路输出电压告警检测*/
		if(dc_v[1] <= 20){
			rtu_buff[136] = (ctrl | 0X0020); // 设置位5，表示第2路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFDF); // 清除位5，表示第2路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第3路输出电压告警检测*/
		if(dc_v[2] <= 20){
			rtu_buff[136] = (ctrl | 0X0040); // 设置位6，表示第3路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFBF); // 清除位6，表示第3路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第4路输出电压告警检测*/
		if(dc_v[3] <= 20){
			rtu_buff[136] = (ctrl | 0X0080); // 设置位7，表示第4路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFF7F); // 清除位7，表示第4路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第5路输出电压告警检测*/
		if(dc_v[4] <= 20){
			rtu_buff[136] = (ctrl | 0X0100); // 设置位8，表示第5路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFFF - 0X0100); // 清除位8，表示第5路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第6路输出电压告警检测*/
		if(dc_v[5] <= 20){
			rtu_buff[136] = (ctrl | 0X0200); // 设置位9，表示第6路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFFF - 0X0200); // 清除位9，表示第6路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第7路输出电压告警检测*/
		if(dc_v[6] <= 20){
			rtu_buff[136] = (ctrl | 0X0400); // 设置位10，表示第7路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFFF - 0X0400); // 清除位10，表示第7路电压正常
		}
		ctrl = rtu_buff[136];
		
		/*第8路输出电压告警检测*/
		if(dc_v[7] <= 20){
			rtu_buff[136] = (ctrl | 0X0800); // 设置位11，表示第8路电压低
		}else{
			rtu_buff[136] = (ctrl & 0XFFFF - 0X0800); // 清除位11，表示第8路电压正常
		}

		/*电池掉线警告*/
		if(BAT_STATE1 == 0){
			rtu_buff[136] = (ctrl | 0X1000); // 设置位12，表示电池掉线
		}else{
			rtu_buff[136] = (ctrl & 0XEFFF); // 清除位12，表示电池正常
		}
			
							// 136寄存器定义（电源告警寄存器）
							// 位0（0x0001）: AC电源状态 - 0=正常，1=异常（PG引脚检测）
							// 位1（0x0002）: 电量告警 - 1=电池容量≤20%，0=电池容量>20%
							// 位2（0x0004）: 高温告警 - 1=设备温度≥50℃，0=设备温度<50℃
							// 位3（0x0008）: 低温告警 - 1=设备温度≤-20℃，0=设备温度>-20℃
							// 位4（0x0010）: 第1路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位5（0x0020）: 第2路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位6（0x0040）: 第3路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位7（0x0080）: 第4路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位8（0x0100）: 第5路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位9（0x0200）: 第6路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位10（0x0400）: 第7路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位11（0x0800）: 第8路输出电压告警 - 1=电压≤20V，0=电压>20V
							// 位12（0x1000）: 电池掉线告警 - 1=电池未连接，0=电池已连接
							// 位13-15: 预留未使用
							ctrl = rtu_buff[136]; // 获取当前告警状态
							
							/*AC电源状态检测*/
						if(!LL_GPIO_IsInputPinSet(PG_GPIO_Port,PG_Pin)){        
								rtu_buff[136] = (ctrl & 0XFFFE); // 清除位0，表示AC电源正常
					  POWER_STATE = 1;
						}
						else {
							rtu_buff[136] = (ctrl | 0X0001); // 设置位0，表示AC电源异常
					  POWER_STATE = 0;
						}
						ctrl = rtu_buff[136];
						
						/*电量告警检测*/
						if(SOC <= 20){
							rtu_buff[136] = (ctrl | 0X0002); // 设置位1，表示电量低
						}else{
					rtu_buff[136] = (ctrl & 0XFFFD); // 清除位1，表示电量正常
						}
						ctrl = rtu_buff[136];
						
						/*高温告警检测*/
						if(device_tem >= 50){
							rtu_buff[136] = (ctrl | 0X0004); // 设置位2，表示高温
						}else{
					rtu_buff[136] = (ctrl & 0XFFFB); // 清除位2，表示温度正常
						}
						ctrl = rtu_buff[136];
						
						/*低温告警检测*/
						if(device_tem <= -20){
							rtu_buff[136] = (ctrl | 0X0008); // 设置位3，表示低温
						}else{
					rtu_buff[136] = (ctrl & 0XFFF7); // 清除位3，表示温度正常
						}
						ctrl = rtu_buff[136];
					  
						/*第1路输出电压告警检测*/
						if(dc_v[0] <= 20){
							rtu_buff[136] = (ctrl | 0X0010); // 设置位4，表示第1路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFEF); // 清除位4，表示第1路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第2路输出电压告警检测*/
						if(dc_v[1] <= 20){
							rtu_buff[136] = (ctrl | 0X0020); // 设置位5，表示第2路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFDF); // 清除位5，表示第2路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第3路输出电压告警检测*/
						if(dc_v[2] <= 20){
							rtu_buff[136] = (ctrl | 0X0040); // 设置位6，表示第3路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFBF); // 清除位6，表示第3路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第4路输出电压告警检测*/
						if(dc_v[3] <= 20){
							rtu_buff[136] = (ctrl | 0X0080); // 设置位7，表示第4路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFF7F); // 清除位7，表示第4路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第5路输出电压告警检测*/
						if(dc_v[4] <= 20){
							rtu_buff[136] = (ctrl | 0X0100); // 设置位8，表示第5路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFFF - 0X0100); // 清除位8，表示第5路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第6路输出电压告警检测*/
						if(dc_v[5] <= 20){
							rtu_buff[136] = (ctrl | 0X0200); // 设置位9，表示第6路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFFF - 0X0200); // 清除位9，表示第6路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第7路输出电压告警检测*/
						if(dc_v[6] <= 20){
							rtu_buff[136] = (ctrl | 0X0400); // 设置位10，表示第7路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFFF - 0X0400); // 清除位10，表示第7路电压正常
						}
						ctrl = rtu_buff[136];
						
						/*第8路输出电压告警检测*/
						if(dc_v[7] <= 20){
							rtu_buff[136] = (ctrl | 0X0800); // 设置位11，表示第8路电压低
						}else{
					rtu_buff[136] = (ctrl & 0XFFFF - 0X0800); // 清除位11，表示第8路电压正常
						}
		
		if(POWER_STATE == 0){
		if(!LL_GPIO_IsInputPinSet(CTRL_BAT_GPIO_Port,CTRL_BAT_Pin)){
			osDelay(200);
			if(!LL_GPIO_IsInputPinSet(CTRL_BAT_GPIO_Port,CTRL_BAT_Pin)){
				BAT_EN = 0;
				ctrl_1 = 1;
			}
		}
		if(ctrl_1 == 0) {
			if(LL_GPIO_IsInputPinSet(CTRL_BAT_GPIO_Port,CTRL_BAT_Pin)){
				osDelay(200);
				if(LL_GPIO_IsInputPinSet(CTRL_BAT_GPIO_Port,CTRL_BAT_Pin)){
					BAT_EN = 1;
				}
			}
		}
	}
	else{
		BAT_EN = 1;
	}
		
		
	osDelay(200);	

	}	
	
  /* USER CODE END StartDefaultTask */
}

void Start_cmd_Task(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	 /*����ִ��*/
	
 uint8_t tmp ,crc;
 uint16_t cmd_crc;
uint16_t ctrl_temp;
 uint8_t buff[10];
	
 static uint8_t rx_state_pc=0;
 static uint8_t rx_cont=0;
	
	uint8_t cChar;	
	vSemaphoreCreateBinary(xSemaphoreRecf_pc_uart1);	
	xQueueRx_pc_uart1 = xQueueCreate(50, sizeof(uint8_t));
	cmd_crc =0;
	LL_USART_EnableIT_RXNE(USART1);
	osDelay(2000);
	
 
  /* Infinite loop */
  for(;;)
  {
		
		
		            /****************************************************************************************/
					/**************************************03寄存器定义***************************************/
					/** 15 ** 14 ** 13 ** 12 ** 11 ** 10 ** 9 ** 8 ** 7 ** 6 ** 5 ** 4 ** 3 ** 2 ** 1 ** 0 **/
					/**预留**充电**放电**AC供电**12路**11路**10路**9路**8路**7路**6路**5路**4路**3路**2路**1路*/
					/**  -  **  -  **  -  **  -  **未用**未用**未用**未用**未用**未用**未用**未用**未用**未用**未用**  -  **/
					/**
					 * 位定义详细说明：
					 * 位0 (0x0001): 第1路输出控制 - 控制EN_1引脚，置1时开启第1路输出
					 * 位1 (0x0002): 第2路输出控制 - 控制CNT2引脚，置1时开启第2路输出（当前被注释）
					 * 位2-11(0x0004-0x0800): 第3-12路输出控制（当前未实现）
					 * 位12(0x1000): AC供电控制 - 控制EN_AC引脚，置1时开启AC供电
					 * 位13(0x2000): 放电控制 - 与BAT_EN状态一起控制EN_BAT引脚，置1且电池使能时开启放电
					 * 位14(0x4000): 充电控制 - 与ch_stade和BAT_STATE1状态一起控制EN_CH引脚，满足条件时开启充电
					 * 位15(0x8000): 预留位
					 */
		            /****************************************************************************************/			
		

		      // 第1路输出控制
				if(rtu_buff[3]&0X0001){
					LL_GPIO_ResetOutputPin(EN_1_GPIO_Port,EN_1_Pin); // 开启第1路输出
				}
					else {
					LL_GPIO_SetOutputPin(EN_1_GPIO_Port,EN_1_Pin); // 关闭第1路输出
				}
		
				// 第2路输出控制
				if(rtu_buff[3]&0X0002){
					LL_GPIO_ResetOutputPin(EN_2_GPIO_Port,EN_2_Pin); // 开启第2路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_2_GPIO_Port,EN_2_Pin); // 关闭第2路输出
				}
				
				// 第3路输出控制
				if(rtu_buff[3]&0X0004){
					LL_GPIO_ResetOutputPin(EN_3_GPIO_Port,EN_3_Pin); // 开启第3路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_3_GPIO_Port,EN_3_Pin); // 关闭第3路输出
				}
				
				// 第4路输出控制
				if(rtu_buff[3]&0X0008){
					LL_GPIO_ResetOutputPin(EN_4_GPIO_Port,EN_4_Pin); // 开启第4路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_4_GPIO_Port,EN_4_Pin); // 关闭第4路输出
				}
				
				// 第5路输出控制
				if(rtu_buff[3]&0X0010){
					LL_GPIO_ResetOutputPin(EN_5_GPIO_Port,EN_5_Pin); // 开启第5路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_5_GPIO_Port,EN_5_Pin); // 关闭第5路输出
				}
				
				// 第6路输出控制
				if(rtu_buff[3]&0X0020){
					LL_GPIO_ResetOutputPin(EN_6_GPIO_Port,EN_6_Pin); // 开启第6路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_6_GPIO_Port,EN_6_Pin); // 关闭第6路输出
				}
				
				// 第7路输出控制
				if(rtu_buff[3]&0X0040){
					LL_GPIO_ResetOutputPin(EN_7_GPIO_Port,EN_7_Pin); // 开启第7路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_7_GPIO_Port,EN_7_Pin); // 关闭第7路输出
				}
				
				// 第8路输出控制
				if(rtu_buff[3]&0X0080){
					LL_GPIO_ResetOutputPin(EN_8_GPIO_Port,EN_8_Pin); // 开启第8路输出
				}
				else {
					LL_GPIO_SetOutputPin(EN_8_GPIO_Port,EN_8_Pin); // 关闭第8路输出
				}
				
				// 注意：第9-12路输出在硬件上未实现，因为main.h中没有对应的引脚定义
				
				// AC供电控制 (位12)
				if(rtu_buff[3]&0x1000){
      			   LL_GPIO_ResetOutputPin(EN_AC_GPIO_Port,EN_AC_Pin);  // 开启AC供电
				}
				else {
					LL_GPIO_SetOutputPin(EN_AC_GPIO_Port,EN_AC_Pin); // 关闭AC供电
				}
				
				// 电池放电控制 (位13) - 与BAT_EN状态一起控制
				//if((rtu_buff[3]&0x2000) && BAT_STATE){//8
				if(((rtu_buff[3]&0x2000)&& BAT_EN)){//8
					LL_GPIO_ResetOutputPin(EN_BAT_GPIO_Port,EN_BAT_Pin);  // 开启电池放电
				}
					else {
							writeFlashTest();
							LL_GPIO_SetOutputPin(EN_BAT_GPIO_Port,EN_BAT_Pin);  // 关闭电池放电
						}
						
						// 电池充电控制 (位14) - 需满足充电使能、ch_stade和BAT_STATE1条件
						if((rtu_buff[3]&0x4000) && ch_stade ){    //9   //充电条件判断
							LL_GPIO_SetOutputPin(EN_CH_GPIO_Port,EN_CH_Pin);					// 开启电池充电
						}
					else {
								LL_GPIO_ResetOutputPin(EN_CH_GPIO_Port,EN_CH_Pin); // 关闭电池充电
							}
									
					rtu_buff[155] = rtu_buff[3];
       
       if(bat_discharge_indication && bat_charge_indicator)  //电池循环次数
			{
				battery_cyc++;
				bat_charge_indicator = 0;
			}
				       
		      
			 if(rtu_buff[6] != modbue_SlaveAddr){		
		   modbue_SlaveAddr = rtu_buff[6];
			 writeFlashTest();}
							
		   
		   if(rtu_buff[154] != udp_status){		   
		   udp_status = rtu_buff[154];
		   writeFlashTest();
		   }
			 if(rtu_buff[4] != modbue_Baud){		   
		   modbue_Baud = rtu_buff[4];
			  LL_USART_Disable(USART1);
  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
  /**USART1 GPIO Configuration
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USART1 DMA Init */

  /* USART1_TX Init */
  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);

  LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PRIORITY_LOW);

  LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MODE_NORMAL);

  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PERIPH_NOINCREMENT);

  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MEMORY_INCREMENT);

  LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PDATAALIGN_BYTE);

  LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MDATAALIGN_BYTE);

  /* USART1 interrupt Init */
  NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(USART1_IRQn);

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  USART_InitStruct.BaudRate = modbue_Baud*100;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART1, &USART_InitStruct);
  LL_USART_ConfigAsyncMode(USART1);
  LL_USART_Enable(USART1);
  /* USER CODE BEGIN USART1_Init 2 */
  // 启用IDLE中断
	LL_USART_DisableIT_RXNE(USART1);
  LL_USART_EnableIT_IDLE(USART1);
  /* USER CODE END USART1_Init 2 */
		   writeFlashTest();
		   }
		   
		   if(rtu_buff[5] != SOH){		   
		   SOH = rtu_buff[5];
		   writeFlashTest();
		   }
			 
			  if(rtu_buff[7] != battery_cyc){		   
		   battery_cyc = rtu_buff[7];
		   writeFlashTest();
		   }			   		  		   				
			
    osDelay(50);
		 }  
  /* USER CODE END StartDefaultTask */
}





/* USER CODE END Application */

